{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "设置仿真参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import simpy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "初始化仿真对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "RANDOM_SEED = 42\n",
    "REQ_TOTAL = 100 # 总请求数\n",
    "REQ_IAT   = 8.0 # 请求平均到达时间\n",
    "SVR_ST    = 7.0 # 平均服务时间\n",
    "MAX_WAIT  = 3.0 # 等待超时门限\n",
    "\n",
    "latency = [] # 采集请求延迟\n",
    "\n",
    "def request(env, name, server, service_time):\n",
    "    arrive = env.now\n",
    "    print('%7.4f %s: incoming' % (arrive, name))\n",
    "\n",
    "    with server.request() as req:\n",
    "        # 等待服务或超时\n",
    "        results = yield req | env.timeout(MAX_WAIT)\n",
    "        wait = env.now - arrive\n",
    "\n",
    "    if req in results:\n",
    "        # 开始服务\n",
    "        print('%7.4f %s: waited %6.3f' % (env.now, name, wait))\n",
    "        t = random.expovariate(1.0 / service_time)\n",
    "        yield env.timeout(t)\n",
    "        elapsed = env.now - arrive\n",
    "        latency.append(elapsed) # 正常完成的请求，采集延迟\n",
    "        print('%7.4f %s: completed %6.3f' % (env.now, name, elapsed))\n",
    "    else:\n",
    "        # 超时\n",
    "        print('%7.4f %s: time out after %6.3f' % (env.now, name, wait))\n",
    "\n",
    "def workload(env, number, inter_arrival_time, server):\n",
    "    for i in range(number):\n",
    "        req = request(env, 'Request%03d' % i, server, service_time=SVR_ST)\n",
    "        env.process(req)\n",
    "        t = random.expovariate(1.0 / inter_arrival_time)\n",
    "        yield env.timeout(t)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "开始仿真"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 0.0000 Request000: incoming\n",
      " 0.0000 Request000: waited  0.000\n",
      " 0.1773 Request000: completed  0.177\n",
      " 8.1605 Request001: incoming\n",
      " 8.1605 Request001: waited  0.000\n",
      " 9.9286 Request001: completed  1.768\n",
      "10.7335 Request002: incoming\n",
      "10.7335 Request002: waited  0.000\n",
      "18.6377 Request002: completed  7.904\n",
      "21.4022 Request003: incoming\n",
      "21.4022 Request003: waited  0.000\n",
      "22.0389 Request003: completed  0.637\n",
      "39.2205 Request004: incoming\n",
      "39.2205 Request004: waited  0.000\n",
      "39.4323 Request004: completed  0.212\n",
      "43.6049 Request005: incoming\n",
      "43.6049 Request005: waited  0.000\n",
      "45.5786 Request006: incoming\n",
      "45.5786 Request006: waited  0.000\n",
      "45.7938 Request007: incoming\n",
      "45.7938 Request007: waited  0.000\n",
      "47.1305 Request006: completed  1.552\n",
      "48.5323 Request005: completed  4.927\n",
      "51.3051 Request007: completed  5.511\n",
      "54.1897 Request008: incoming\n",
      "54.1897 Request008: waited  0.000\n",
      "56.1819 Request009: incoming\n",
      "56.1819 Request009: waited  0.000\n",
      "56.2276 Request009: completed  0.046\n",
      "60.4184 Request008: completed  6.229\n",
      "69.4438 Request010: incoming\n",
      "69.4438 Request010: waited  0.000\n",
      "77.8284 Request010: completed  8.385\n",
      "82.5556 Request011: incoming\n",
      "82.5556 Request011: waited  0.000\n",
      "83.7385 Request011: completed  1.183\n",
      "85.8827 Request012: incoming\n",
      "85.8827 Request012: waited  0.000\n",
      "88.7553 Request012: completed  2.873\n",
      "111.0949 Request013: incoming\n",
      "111.0949 Request013: waited  0.000\n",
      "111.8069 Request013: completed  0.712\n",
      "111.8736 Request014: incoming\n",
      "111.8736 Request014: waited  0.000\n",
      "118.3531 Request014: completed  6.480\n",
      "126.9180 Request015: incoming\n",
      "126.9180 Request015: waited  0.000\n",
      "136.0764 Request015: completed  9.158\n",
      "140.0838 Request016: incoming\n",
      "140.0838 Request016: waited  0.000\n",
      "146.2307 Request017: incoming\n",
      "146.2307 Request017: waited  0.000\n",
      "150.0361 Request018: incoming\n",
      "150.0361 Request018: waited  0.000\n",
      "151.8521 Request017: completed  5.621\n",
      "156.7820 Request018: completed  6.746\n",
      "164.1838 Request019: incoming\n",
      "164.1838 Request019: waited  0.000\n",
      "165.3973 Request016: completed 25.314\n",
      "170.2123 Request019: completed  6.029\n",
      "180.0109 Request020: incoming\n",
      "180.0109 Request020: waited  0.000\n",
      "180.3392 Request020: completed  0.328\n",
      "189.7655 Request021: incoming\n",
      "189.7655 Request021: waited  0.000\n",
      "191.8346 Request022: incoming\n",
      "191.8346 Request022: waited  0.000\n",
      "192.1569 Request021: completed  2.391\n",
      "192.4998 Request023: incoming\n",
      "192.4998 Request023: waited  0.000\n",
      "193.3516 Request024: incoming\n",
      "193.3516 Request024: waited  0.000\n",
      "193.6896 Request022: completed  1.855\n",
      "194.7797 Request023: completed  2.280\n",
      "196.5287 Request024: completed  3.177\n",
      "201.4295 Request025: incoming\n",
      "201.4295 Request025: waited  0.000\n",
      "203.0752 Request025: completed  1.646\n",
      "205.1281 Request026: incoming\n",
      "205.1281 Request026: waited  0.000\n",
      "207.6127 Request027: incoming\n",
      "207.6127 Request027: waited  0.000\n",
      "214.1884 Request027: completed  6.576\n",
      "215.9665 Request028: incoming\n",
      "215.9665 Request028: waited  0.000\n",
      "217.4681 Request029: incoming\n",
      "217.4681 Request029: waited  0.000\n",
      "218.8954 Request030: incoming\n",
      "218.8954 Request030: waited  0.000\n",
      "220.8083 Request029: completed  3.340\n",
      "224.4422 Request026: completed 19.314\n",
      "225.1093 Request028: completed  9.143\n",
      "226.0470 Request030: completed  7.152\n",
      "255.3643 Request031: incoming\n",
      "255.3643 Request031: waited  0.000\n",
      "261.8769 Request032: incoming\n",
      "261.8769 Request032: waited  0.000\n",
      "263.4420 Request031: completed  8.078\n",
      "272.3496 Request032: completed 10.473\n",
      "276.6814 Request033: incoming\n",
      "276.6814 Request033: waited  0.000\n",
      "276.9098 Request033: completed  0.228\n",
      "278.7624 Request034: incoming\n",
      "278.7624 Request034: waited  0.000\n",
      "280.9438 Request034: completed  2.181\n",
      "281.7944 Request035: incoming\n",
      "281.7944 Request035: waited  0.000\n",
      "283.6902 Request036: incoming\n",
      "283.6902 Request036: waited  0.000\n",
      "286.3352 Request036: completed  2.645\n",
      "300.4137 Request037: incoming\n",
      "300.4137 Request037: waited  0.000\n",
      "301.8363 Request035: completed 20.042\n",
      "303.9387 Request037: completed  3.525\n",
      "308.9376 Request038: incoming\n",
      "308.9376 Request038: waited  0.000\n",
      "313.2360 Request038: completed  4.298\n",
      "328.6159 Request039: incoming\n",
      "328.6159 Request039: waited  0.000\n",
      "330.5983 Request039: completed  1.982\n",
      "331.0777 Request040: incoming\n",
      "331.0777 Request040: waited  0.000\n",
      "333.2114 Request040: completed  2.134\n",
      "337.6705 Request041: incoming\n",
      "337.6705 Request041: waited  0.000\n",
      "344.6983 Request042: incoming\n",
      "344.6983 Request042: waited  0.000\n",
      "346.4314 Request042: completed  1.733\n",
      "348.7769 Request043: incoming\n",
      "348.7769 Request043: waited  0.000\n",
      "353.6378 Request041: completed 15.967\n",
      "353.7636 Request043: completed  4.987\n",
      "396.8299 Request044: incoming\n",
      "396.8299 Request044: waited  0.000\n",
      "397.1677 Request044: completed  0.338\n",
      "397.5924 Request045: incoming\n",
      "397.5924 Request045: waited  0.000\n",
      "398.5215 Request046: incoming\n",
      "398.5215 Request046: waited  0.000\n",
      "402.3607 Request046: completed  3.839\n",
      "404.5040 Request045: completed  6.912\n",
      "411.0863 Request047: incoming\n",
      "411.0863 Request047: waited  0.000\n",
      "411.6114 Request048: incoming\n",
      "411.6114 Request048: waited  0.000\n",
      "414.4508 Request047: completed  3.365\n",
      "416.8833 Request048: completed  5.272\n",
      "456.0296 Request049: incoming\n",
      "456.0296 Request049: waited  0.000\n",
      "469.8315 Request049: completed 13.802\n",
      "484.3749 Request050: incoming\n",
      "484.3749 Request050: waited  0.000\n",
      "484.4673 Request051: incoming\n",
      "484.4673 Request051: waited  0.000\n",
      "489.8570 Request051: completed  5.390\n",
      "493.3037 Request050: completed  8.929\n",
      "493.6256 Request052: incoming\n",
      "493.6256 Request052: waited  0.000\n",
      "496.1086 Request053: incoming\n",
      "496.1086 Request053: waited  0.000\n",
      "497.0548 Request054: incoming\n",
      "497.0548 Request054: waited  0.000\n",
      "500.1022 Request053: completed  3.994\n",
      "500.7959 Request052: completed  7.170\n",
      "501.8919 Request055: incoming\n",
      "501.8919 Request055: waited  0.000\n",
      "504.0317 Request055: completed  2.140\n",
      "518.5807 Request054: completed 21.526\n",
      "518.5822 Request056: incoming\n",
      "518.5822 Request056: waited  0.000\n",
      "519.9598 Request056: completed  1.378\n",
      "524.1367 Request057: incoming\n",
      "524.1367 Request057: waited  0.000\n",
      "538.4463 Request057: completed 14.310\n",
      "543.6374 Request058: incoming\n",
      "543.6374 Request058: waited  0.000\n",
      "546.4730 Request059: incoming\n",
      "546.4730 Request059: waited  0.000\n",
      "547.6341 Request059: completed  1.161\n",
      "550.7685 Request058: completed  7.131\n",
      "553.9848 Request060: incoming\n",
      "553.9848 Request060: waited  0.000\n",
      "559.4111 Request060: completed  5.426\n",
      "565.4859 Request061: incoming\n",
      "565.4859 Request061: waited  0.000\n",
      "570.7763 Request061: completed  5.290\n",
      "577.5491 Request062: incoming\n",
      "577.5491 Request062: waited  0.000\n",
      "577.5537 Request063: incoming\n",
      "577.5537 Request063: waited  0.000\n",
      "577.7110 Request064: incoming\n",
      "577.7110 Request064: waited  0.000\n",
      "580.2916 Request062: completed  2.743\n",
      "590.1836 Request064: completed 12.473\n",
      "594.5884 Request065: incoming\n",
      "594.5884 Request065: waited  0.000\n",
      "595.0061 Request065: completed  0.418\n",
      "596.0789 Request063: completed 18.525\n",
      "597.5281 Request066: incoming\n",
      "597.5281 Request066: waited  0.000\n",
      "614.3586 Request067: incoming\n",
      "614.3586 Request067: waited  0.000\n",
      "615.0750 Request068: incoming\n",
      "615.0750 Request068: waited  0.000\n",
      "615.6488 Request069: incoming\n",
      "615.6488 Request069: waited  0.000\n",
      "616.6107 Request069: completed  0.962\n",
      "618.0837 Request066: completed 20.556\n",
      "619.0172 Request067: completed  4.659\n",
      "625.0824 Request068: completed 10.007\n",
      "627.2626 Request070: incoming\n",
      "627.2626 Request070: waited  0.000\n",
      "632.4217 Request071: incoming\n",
      "632.4217 Request071: waited  0.000\n",
      "632.8491 Request070: completed  5.586\n",
      "634.8854 Request072: incoming\n",
      "634.8854 Request072: waited  0.000\n",
      "636.5514 Request072: completed  1.666\n",
      "639.2867 Request073: incoming\n",
      "639.2867 Request073: waited  0.000\n",
      "645.4867 Request074: incoming\n",
      "645.4867 Request074: waited  0.000\n",
      "646.8355 Request071: completed 14.414\n",
      "647.2833 Request075: incoming\n",
      "647.2833 Request075: waited  0.000\n",
      "648.1015 Request074: completed  2.615\n",
      "648.4502 Request073: completed  9.164\n",
      "654.6296 Request075: completed  7.346\n",
      "689.9125 Request076: incoming\n",
      "689.9125 Request076: waited  0.000\n",
      "694.5239 Request077: incoming\n",
      "694.5239 Request077: waited  0.000\n",
      "695.0150 Request076: completed  5.103\n",
      "695.5557 Request078: incoming\n",
      "695.5557 Request078: waited  0.000\n",
      "696.3054 Request077: completed  1.782\n",
      "698.8567 Request079: incoming\n",
      "698.8567 Request079: waited  0.000\n",
      "700.5979 Request079: completed  1.741\n",
      "700.9488 Request080: incoming\n",
      "700.9488 Request080: waited  0.000\n",
      "701.5379 Request081: incoming\n",
      "701.5379 Request081: waited  0.000\n",
      "701.7681 Request078: completed  6.212\n",
      "703.6178 Request082: incoming\n",
      "703.6178 Request082: waited  0.000\n",
      "704.1323 Request082: completed  0.514\n",
      "707.9295 Request080: completed  6.981\n",
      "718.0461 Request081: completed 16.508\n",
      "719.3259 Request083: incoming\n",
      "719.3259 Request083: waited  0.000\n",
      "721.5004 Request084: incoming\n",
      "721.5004 Request084: waited  0.000\n",
      "722.4939 Request084: completed  0.993\n",
      "723.4292 Request085: incoming\n",
      "723.4292 Request085: waited  0.000\n",
      "727.0649 Request083: completed  7.739\n",
      "729.3540 Request085: completed  5.925\n",
      "745.3597 Request086: incoming\n",
      "745.3597 Request086: waited  0.000\n",
      "750.4792 Request087: incoming\n",
      "750.4792 Request087: waited  0.000\n",
      "751.9578 Request087: completed  1.479\n",
      "756.1072 Request086: completed 10.747\n",
      "763.6603 Request088: incoming\n",
      "763.6603 Request088: waited  0.000\n",
      "764.4760 Request089: incoming\n",
      "764.4760 Request089: waited  0.000\n",
      "767.6081 Request088: completed  3.948\n",
      "768.8809 Request089: completed  4.405\n",
      "768.8833 Request090: incoming\n",
      "768.8833 Request090: waited  0.000\n",
      "776.7157 Request090: completed  7.832\n",
      "779.3306 Request091: incoming\n",
      "779.3306 Request091: waited  0.000\n",
      "780.0559 Request091: completed  0.725\n",
      "812.4950 Request092: incoming\n",
      "812.4950 Request092: waited  0.000\n",
      "815.3962 Request092: completed  2.901\n",
      "816.6166 Request093: incoming\n",
      "816.6166 Request093: waited  0.000\n",
      "818.6179 Request093: completed  2.001\n",
      "832.4417 Request094: incoming\n",
      "832.4417 Request094: waited  0.000\n",
      "834.1295 Request095: incoming\n",
      "834.1295 Request095: waited  0.000\n",
      "836.4149 Request095: completed  2.285\n",
      "836.6089 Request094: completed  4.167\n",
      "838.5133 Request096: incoming\n",
      "838.5133 Request096: waited  0.000\n",
      "840.8127 Request097: incoming\n",
      "840.8127 Request097: waited  0.000\n",
      "845.4961 Request098: incoming\n",
      "845.4961 Request098: waited  0.000\n",
      "845.8595 Request098: completed  0.363\n",
      "851.8900 Request099: incoming\n",
      "851.8900 Request099: waited  0.000\n",
      "854.6433 Request097: completed 13.831\n",
      "856.4852 Request096: completed 17.972\n",
      "864.5464 Request099: completed 12.656\n"
     ]
    }
   ],
   "source": [
    "random.seed(RANDOM_SEED)\n",
    "env = simpy.Environment()\n",
    "\n",
    "server = simpy.Resource(env, capacity=1)\n",
    "env.process(workload(env, REQ_TOTAL, REQ_IAT, server))\n",
    "env.run()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "记录延迟数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(\"latency.csv\", \"w+\") as tracefile:\n",
    "    tracefile.write(\"latency\\n\")\n",
    "    tracefile.writelines([str(l) + '\\n' for l in latency])"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "f487011d6c19380a0f12fb28ca8659fdd2afd3ccddcfad5755f4bb9819179fc2"
  },
  "kernelspec": {
   "display_name": "Python 3.9.7 64-bit ('lab': conda)",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
